<?php /* 
==================================================
TextCMS -- simple plain/text CMS with GPL licence
CMS common functions module
(c) 2008, 4X_Pro
Visit us online: http://textcms.ru
==================================================
*/

/** Получение hurl страницы по id. 
**/
function cmsmain_get_hurl($id) {
  $filename=file_exists(cms_basedir().'content.txt') ? cms_basedir().'content.txt' : cms_basedir().'content.def';
  $fh=fopen($filename,'r');
  $result=false;  
  if (!$fh) {
    trigger_error(E_USER_ERROR,'Не удалось открыть файл '.$filename.'!');
  }  
  else {
    while (!$result && $buffer=fgets($fh)) {
      if ($buffer) {
        $data=cms_page_parse($buffer);
        if ($data['id']==$id) $result=$data['url'];
      }
    }
    fclose($fh);
  }
  return $result;
}

/** Функция установки значений полей форм в соответствии с параметрами в хеш-массиве data.
(Ключи массива должны соответствовать именам полей.) 
Если ключ в массиве отсутствует, поле остается без изменений 
(таким образом, имеет смысл прописывать в качестве значений полей значения по умолчанию).
**/
function cmsmain_html_set($html,$data,$params=false) {
  $count = preg_match_all('|(<input[^>]+?>)|is',$html,$inputs);
  for ($i=0; $i<$count; $i++) {
    $name=_cmsmain_html_getparam($inputs[0][$i],'name');
    if (($newvalue=_cmsmain_html_data($data,$name))!==false) {
      $newstr=false;
      $value=_cmsmain_html_getparam($inputs[0][$i],'value');
      $type=_cmsmain_html_getparam($inputs[0][$i],'type');
      if ($type=="radio" || $type=="checkbox") {
        if ($value==$newvalue) {
          $newstr=$inputs[0][$i];
          if (strrpos($newstr,'/>')===strlen($newstr)-2) $newstr=str_replace('/>',' checked="checked"/>',$newstr);
          else $newstr=str_replace('>',' checked>',$newstr);
        }
	      else $newstr=preg_replace('|\s+checked(=\S+?)?([\s/>])|s','$2',$inputs[0][$i]);
      }
      else {
        if (preg_match('|\s+value=[\'"]?'.$value.'[\'"]?([\s/>])|is',$inputs[0][$i])) {
          $newstr=preg_replace('|\s+value=[\'"]?'.$value.'[\'"]?([\s/>])|is',' value="'.htmlspecialchars($data[$name]).'"$1',$inputs[0][$i]);
        }
        else $newstr=preg_replace('|(/?>)$|s',' value="'.$newvalue.'"$1',$inputs[0][$i]);
      }
      if ($newstr) $html=str_replace($inputs[0][$i],$newstr,$html);
    }
  }
  $count = preg_match_all('|(<textarea[^>]+?>)(.*?)</textarea>|is',$html,$textareas);
  for ($i=0; $i<$count; $i++) {
    $name=_cmsmain_html_getparam($textareas[1][$i],'name');
    if (($newvalue=_cmsmain_html_data($data,$name))!==false) {
      $newstr=$textareas[1][$i].$newvalue.'</textarea>';
      $html=str_replace($textareas[0][$i],$newstr,$html);
    }
  }
  $count = preg_match_all('|(<select[^>]+?>)(.*?)</select>|is',$html,$selects);
  for ($i=0; $i<$count; $i++) {
    $name=_cmsmain_html_getparam($selects[1][$i],'name');
		$name=str_replace('[]','',$name); // убираем для multiselect
    if (isset($params[$name]) && is_array($params[$name])) {
      $newselects = '';
      foreach ($params[$name] as $key=>$value) {
        if ($value=='') $value=$key;
        $newselects.='<option value="'.htmlspecialchars($key).'">'.htmlspecialchars($value).'</option>';
      }
      $newbigstr=preg_replace('|</select>|is',$newselects.'</select>',$selects[0][$i]);
      $selects[2][$i].=$newselects;
    }
    else $newbigstr=$selects[0][$i];
    if (isset($data[$name])) {
			if (!is_array($data[$name])) $data[$name]=array($data[$name]);
      $optcount = preg_match_all('|<option([^>]+?)>(.*?)<|is',$selects[2][$i].'<',$options);
      for ($j=0; $j<$optcount; $j++) {
        $value=_cmsmain_html_getparam($options[1][$j],'value');
        if (in_array($value,$data[$name])) {
          $newstr=$options[0][$j];
          $newstr=preg_replace('|(<option[^>]+?)>|s','$1 selected="selected">',$newstr);
        }
	      else $newstr=preg_replace('|\s+selected(=\S+?)?([\s/>])|s','$2',$options[0][$j]);
        $newbigstr=str_replace($options[0][$j],$newstr,$newbigstr);
      }
      $html=str_replace($selects[0][$i],$newbigstr,$html);
    }
  }
  return $html;
}

/** Извлечение параметра из html-тега. **/
function _cmsmain_html_getparam($input,$param) {
  if (!preg_match('|\s+'.$param.'="(.*?)"|is',$input,$matches)) {
    if (!preg_match('|\s+'.$param.'=\'(.*?)\'|is',$input,$matches)) {
      if (!preg_match('|\s+'.$param.'=(\S+?)|is',$input,$matches)) $matches[1]=''; 
    }
  }
  return $matches[1];
}

/** Извлекает данные из массива и применяет к ним htmlspecialchars. 
На данный момент не поддерживается обработка спецсимволов (типа [] для вложенных массивов)
**/
function _cmsmain_html_data($data,$name) {
  if (isset($data[$name])) return htmlspecialchars($data[$name]);
  else return false;
}

/**  Функция сохраняет информацию о странице в файл.
TODO: доделать сортировку по уровню вложенности перед сохранением.
**/
function cmsmain_pageinfo_save($newdata,$oldurl=false) {
  $filename=file_exists(cms_basedir().'content.txt') ? cms_basedir().'content.txt' : cms_basedir().'content.def';
  $fh=fopen($filename,'r');
  $lastdata=0;
  $lastsort=0;  
  $save=array();
  $found=false;
  while ($curbuffer=fgets($fh)) {
    $data=cms_page_parse($curbuffer);
    $lastdata=max($lastdata,$data['id']); // фиксируем последний использованный id
    if (!$newdata['sort']) $lastsort=max($lastsort,$data['sort']); // фиксируем последний номер сортировки
    if (isset($newdata['id']) && $data['id']==$newdata['id']) {
      $save[]=$newdata;
      $found=true;
    }
    elseif ($oldurl && strpos($data['url'],$oldurl.'/')===0) { // если это дочерний элемент сохраняемого элемента, меняем ему URL также
      $data['url']=str_replace($oldurl.'/',$newdata['url'].'/',$data['url']);
      $save[]=$data;
    }
    else $save[]=$data;      
  }
  fclose($fh);
  if (!isset($newdata['id']) || !$found) {
    if (!isset($newdata['id']) || !$newdata['id']) $newdata['id']=$lastdata+1; // фиксируем новый id как максимальный + 1
    if (!$newdata['sort']) $newdata['sort']=$lastsort+1; // фиксируем номер сортировки
    $save[]=$newdata;
  }
  cmsmain_save_pageinfo_saveall($save);
  return $newdata['id'];
}

/** Функция сохранения массива со страницами в файл с предварительной сортировкой по уровню вложенности или порядковому номеру **/
function cmsmain_save_pageinfo_saveall($save) {
  usort($save,create_function('$a,$b','
    $cmp=substr_count($a["url"],"/")-substr_count($b["url"],"/");
    if ($cmp==0) return strcmp($a["url"],$b["url"]);
    else return $cmp;    
  '));
  
  $filename=cms_basedir().'content.txt'; // сохраняем всегда в content.txt, вне зависимости от того, откуда читали данные!
  $tmpname=str_replace('.txt','.tmp',$filename);
  $fh=fopen($tmpname,'w');   
  if (!$fh) {
    trigger_error(E_USER_ERROR,'Не удалось открыть файл '.$filename.' на запись!');    
  }
  flock($fh,LOCK_EX);  
  $buffer='';
  foreach ($save as $curdata) {
    foreach ($curdata as $key=>$value) $curdata[$key]=str_replace(':','&#58;',$curdata[$key]);
    $buffer.=$curdata['url'].':'.$curdata['id'].':'.$curdata['template'].':'.$curdata['state'].':'.$curdata['lastmod'].':'.$curdata['date'].':'.$curdata['sort'].':'.$curdata['title']."\n";
  }
  fputs($fh,$buffer);
  fclose($fh);
  unlink($filename);
  rename($tmpname,$filename);
  if (cms_module_load('sitemap')) sitemap_build($save);
}

/** Получение списка каталогов с шаблонами в виде массива**/
function cmsmain_get_templates() {
  $dh = opendir('./template');
  $result=array();
  while ($curfile=readdir($dh)) {
    if ($curfile!='.' && $curfile!='..' && is_dir('./template/'.$curfile)) $result[$curfile]=$curfile;
  }
  closedir($dh);
  return $result;
}

/** Сохранение данных страницы в файл **/
function cmsmain_page_save($id,$draft,$text) {
  $filename=cms_page_filename($id,$draft);
  $fh=fopen($filename,'w');
  if (!$fh) return false;
  else {
    fwrite($fh,$text);
    fclose($fh);
  }
  if (!$draft) {
    $draftname=cms_page_filename($id,true);
    if (file_exists($draftname)) unlink($draftname);
  }
  return true;
}


/** Функция для замены конструкций вида #ключ# на значение из хеш массива, 
соответствующее данному ключу. Рекомендуется пользоваться этой функцией при 
обработке шаблонов.  
**/
function cmsmain_replace($page,$data) {
  foreach ($data as $key=>$value) if (!is_array($value) && !is_object($value)) $page=str_replace('#'.$key.'#',$value,$page);
  return $page;
}


/**  **/
function cmsmain_transliterate($text) {
  $text=str_replace(array("А","Б","В","Г","Д","Е","Ё","Ж","З","И","Й","К","Л","М","Н","О","П","Р","С","Т","У","Ф","Х","Ц","Ч","Ш","Щ","Ь","Ы","Ъ","Э","Ю","Я"),
    array("A","B","V","G","D","E","Yo","J","Z","I","I","K","L","M","N","O","P","R","S","T","U","F","H","C","Ch","Sh","Sch","","Y","","E","Yu","Ya"),$text);
  $text=str_replace(array("а","б","в","г","д","е","ё","ж","з","и","й","к","л","м","н","о","п","р","с","т","у","ф","х","ц","ч","ш","щ","ь","ы","ъ","э","ю","я"),
    array("a","b","v","g","d","e","yo","j","z","i","i","k","l","m","n","o","p","r","s","t","u","f","h","c","ch","sh","sch","","y","","e","yu","ya"),$text);
  return $text;
}

